#pragma once

#ifndef NESTAGENT_H_
#define NESTAGENT_H_


/*
	Creator: Nathan Perry
	Class: Nest Agent
	Purpose: To control the actions of the Nest Object(called GUINest in this case). The Nest Agent will control when the
	GUINest starts and stops animating, as well as telling the associated Camera Agent that the 

*/
//#include "kittingcell.h"
#include "PartRobot.h"
#include "Agent.h"
#include "Nest.h"
#include "GUINestInterface.h"

#include "Camera.h"
#include "Lane.h"
class PartRobot;
class Lane;
class Agent;
class Camera;


class NestAgent : public Agent, public Nest
{
private:
	GUINestInterface* guiNest;
	PartRobot* partsRobot;
	Camera* camera;
	Lane* lane;
	bool purging;
	int numberOfCameraCalls;

	//Timer to tell the nest when it should be full
	class CallCameraTimer : public Thread {
	public:
		CallCameraTimer() {}
		CallCameraTimer(NestAgent* na) {
			myNest = na;
		}
		~CallCameraTimer();
		virtual void run() {
			qDebug("Nest Timer: Ask the camera if youre full");
			sleep(5);
			myNest->msgIThinkYoureFull();
			stop();
		}
	private:
		NestAgent* myNest;
	};

	//Timer to tell the nest when it should be done purging
	class PurgeNestTimer : public Thread {
	public:
		PurgeNestTimer() {}
		PurgeNestTimer(NestAgent* na) {
			myNest = na;
		}
		~PurgeNestTimer();
		virtual void run() {
			sleep(1);
			myNest->msgPleaseStopPurging();
			myNest->msgPleaseGetParts(myNest->partType);
			stop();
		}
	private:
		NestAgent* myNest;
	};

public:

	enum NestState {None, Ready_To_Purge, Request_New_Parts, Purging, PossiblyFull, GoodPicture, BadPicture};

	PurgeNestTimer* pnTimer;
	CallCameraTimer* ccTimer;
	PartType partType;
	NestState state;
	bool testing;

	//Constructor
	NestAgent(std::string name); 
	
	//Assessors
	void setPartRobot(PartRobot* robot);
	void setCamera(Camera* ca);
	void setLane(Lane* la);
	void setGUI(GUINestInterface* gui);
	GUINest* getGUI();

	//Messages
	//From Lane
	void msgIThinkYoureFull();
	//From Lane
	void msgPleaseStopPurging();
	//From GUINest
	void msgPartWasTaken();
	//From Camera
	void msgHereIsAPicture(Picture p);
	//From PartRobot
	void msgPleaseGetParts(PartType p);
	//Scheduler
	virtual bool pickAndExecuteAnAction();

	//Actions
	//To PartRobot
	void tellPartRobotImStable();
	//To Lane
	void givePartTypeToLane();
	//To Camera
	void tellCameraIThinkImFull();
	//To Camera
	void tellCameraIThinkImFullTimer();

	void handleBreak();

	void handleFix();
	//Non-normative
	void reactToPossibleLaneJam(bool flag);
	//To GUI
	void tellGUIToStart();
	//To GUI
	void tellGUIToPurge(bool flag);
	//To GUI
	void tellGUIToStop();

};

#endif
